package org.jeecg.pms.utils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.jeecg.pms.aspect.enums.CompareStatus;

public class CompareObejct<T> {

	private CompareStatus status;
	/**
	 * 之前原始的值
	 */
	private T original;
	/**
	 * 当前的值
	 */
	private T current;

	public CompareStatus getStatus() {
		return status;
	}

	public T getOriginal() {
		return original;
	}

	public void setOriginal(T original) {
		this.original = original;
	}

	public T getCurrent() {
		return current;
	}

	public void setCurrent(T current) {
		this.current = current;
	}

	public Map<String, Map<String, Object>> contrastObj(Class<T> cls, List<String> ignoreFields) {
		Map<String, Map<String, Object>> result = new HashMap<String, Map<String, Object>>();
		if (this.original == null) {
			this.status = CompareStatus.NEW;
			return result;
		}
		if (this.status == CompareStatus.REMOVE) {
			return result;
		}
		boolean isEqual = true;
		try {
			// Class clazz = this.original.getClass();
			Field[] fields = cls.getDeclaredFields();
			for (Field field : fields) {
				if(ignoreFields.contains(field.getName()) || "serialVersionUID".endsWith(field.getName())){
					continue;
				}
				PropertyDescriptor pd = new PropertyDescriptor(field.getName(), cls);
				Method getMethod = pd.getReadMethod();
				Object o1 = getMethod.invoke(this.original);
				Object o2 = getMethod.invoke(this.current);
				
				String s1 = o1 == null ? "" : o1.toString();// 避免空指针异常
				String s2 = o2 == null ? "" : o2.toString();// 避免空指针异常
				if(field.getType() == Date.class && o1!=null){
					s1 = DateFormatUtils.format((Date) o1, "yyyy-MM-dd HH:mm:ss");
				}else if(field.getType() == BigDecimal.class && o1!=null){
					s1 = ((BigDecimal) o1).stripTrailingZeros().toPlainString();
				}else if((field.getType() == Double.class || field.getType() == Float.class) && o1!=null) {
					s1 = new BigDecimal(String.valueOf(o1)).stripTrailingZeros().toPlainString();
				}
				if(field.getType() == Date.class && o2!=null){
					s2 = DateFormatUtils.format((Date) o2, "yyyy-MM-dd HH:mm:ss");
				}else if(field.getType() == BigDecimal.class && o2!=null){
					s2 = ((BigDecimal) o2).stripTrailingZeros().toPlainString();
				}else if((field.getType() == Double.class || field.getType() == Float.class) && o2!=null){
					s2 = new BigDecimal(String.valueOf(o2)).stripTrailingZeros().toPlainString();
				}
				
				
				// 思考下面注释的这一行：会bug的，虽然被try catch了，程序没报错，但是结果不是我们想要的
				// if (!o1.toString().equals(o2.toString())) {
				if (!s1.equals(s2)) {
					// textList.add("不一样的属性：" + field.getName() + " 属性值：[" + s1
					// + "," + s2 + "]");
					isEqual = false;
					Map<String, Object> diff = new HashMap<>();
					diff.put("oldValue", s1);
					diff.put("newValue", s2);
					result.put(field.getName(), diff);
				}
			}
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		if (isEqual) {
			this.status = CompareStatus.NO_CHANGE;
		} else {
			this.status = CompareStatus.CHANGE;
		}
		return result;
	}

}